package com.joker.airoleplayplatformback.service.impl;

import com.joker.airoleplayplatformback.service.PerformanceMonitorService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StopWatch;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

/**
 * 性能监控服务
 *
 * @author feixiang.li
 * @since 2025-09-27
 */
@Slf4j
@Service
public class PerformanceMonitorServiceImpl implements PerformanceMonitorService {

    // 统计各个步骤的执行次数和总时间
    private final ConcurrentHashMap<String, AtomicLong> stepCountMap = new ConcurrentHashMap<>();
    private final ConcurrentHashMap<String, AtomicLong> stepTotalTimeMap = new ConcurrentHashMap<>();

    /**
     * 记录步骤性能数据
     */
    @Override
    public void recordStepPerformance(String stepName, long timeMillis) {
        stepCountMap.computeIfAbsent(stepName, k -> new AtomicLong(0)).incrementAndGet();
        stepTotalTimeMap.computeIfAbsent(stepName, k -> new AtomicLong(0)).addAndGet(timeMillis);

        log.debug("步骤性能记录: {} - {}ms", stepName, timeMillis);
    }

    /**
     * 记录完整流程性能
     */
    @Override
    public void recordCompleteProcess(StopWatch stopWatch) {
        if (stopWatch.getTaskCount() == 0) {
            return;
        }

        StringBuilder performanceReport = new StringBuilder();
        performanceReport.append("\n========== 语音处理性能报告 ==========\n");
        performanceReport.append(String.format("总耗时: %dms\n", stopWatch.getTotalTimeMillis()));
        performanceReport.append("步骤详情:\n");

        for (StopWatch.TaskInfo taskInfo : stopWatch.getTaskInfo()) {
            performanceReport.append(String.format("  %-15s: %6dms (%.1f%%)\n",
                    taskInfo.getTaskName(),
                    taskInfo.getTimeMillis(),
                    (double) taskInfo.getTimeMillis() / stopWatch.getTotalTimeMillis() * 100));

            // 记录到统计数据中
            recordStepPerformance(taskInfo.getTaskName(), taskInfo.getTimeMillis());
        }

        performanceReport.append("=====================================");
        log.info(performanceReport.toString());
    }

    /**
     * 获取性能统计报告
     */
    @Override
    public String getPerformanceReport() {
        if (stepCountMap.isEmpty()) {
            return "暂无性能数据";
        }

        StringBuilder report = new StringBuilder();
        report.append("\n========== 累计性能统计报告 ==========\n");

        stepCountMap.forEach((stepName, count) -> {
            long totalTime = stepTotalTimeMap.get(stepName).get();
            double avgTime = (double) totalTime / count.get();

            report.append(String.format("%-15s: 执行%4d次, 总耗时%6dms, 平均%6.1fms\n",
                    stepName, count.get(), totalTime, avgTime));
        });

        report.append("====================================");
        return report.toString();
    }

    /**
     * 清空统计数据
     */
    @Override
    public void clearStatistics() {
        stepCountMap.clear();
        stepTotalTimeMap.clear();
        log.info("性能统计数据已清空");
    }

    /**
     * 获取步骤平均耗时
     */
    @Override
    public double getStepAverageTime(String stepName) {
        AtomicLong count = stepCountMap.get(stepName);
        AtomicLong totalTime = stepTotalTimeMap.get(stepName);

        if (count == null || totalTime == null || count.get() == 0) {
            return 0.0;
        }

        return (double) totalTime.get() / count.get();
    }

    /**
     * 检查是否有性能瓶颈
     */
    @Override
    public void checkPerformanceBottleneck() {
        stepCountMap.forEach((stepName, count) -> {
            if (count.get() >= 10) { // 至少执行10次才进行分析
                double avgTime = getStepAverageTime(stepName);

                // 设定各步骤的性能阈值（毫秒）
                double threshold = getPerformanceThreshold(stepName);

                if (avgTime > threshold) {
                    log.warn("性能瓶颈警告: {} 平均耗时 {:.1f}ms，超过阈值 {:.1f}ms",
                            stepName, avgTime, threshold);
                }
            }
        });
    }

    /**
     * 获取各步骤的性能阈值
     */
    @Override
    public double getPerformanceThreshold(String stepName) {
        switch (stepName) {
            case "上传音频到OSS":
                return 2000.0; // 2秒
            case "ASR语音识别":
                return 3000.0; // 3秒
            case "LLM生成回复":
                return 5000.0; // 5秒
            case "TTS语音合成":
                return 3000.0; // 3秒
            case "上传AI音频":
                return 2000.0; // 2秒
            case "保存用户消息":
            case "保存AI消息":
                return 500.0;  // 0.5秒
            case "构建对话上下文":
            case "发送WebSocket消息":
            case "清理临时文件":
                return 200.0;  // 0.2秒
            default:
                return 1000.0; // 默认1秒
        }
    }
}
